home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2007 December
/
PCWKCD1207B.iso
/
Blogowanie poza sfera
/
Flock 1.0 beta
/
flock-1.0RC3.en-US.win32.exe
/
flock
/
components
/
flockProfiler.js
< prev
next >
Wrap
Text File
|
2007-10-18
|
13KB
|
401 lines
// vim: ts=2 sw=2 expandtab cindent
//
// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2007
// http://flock.com
//
// This file may be used under the terms of of the
// GNU General Public License Version 2 or later (the "GPL"),
// http://www.gnu.org/licenses/gpl.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// END FLOCK GPL
//
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const CLASS_ID = Components.ID("{2fd8e108-f21b-11db-8314-0800200c9a66}");
const CONTRACT_ID = "@flock.com/profiler;1";
const CATEGORY_COMPONENT_NAME = "Flock Profiler Component";
const GRAPH_HOST = "dippy.hq.flock.com";
const CREATEGRAPH_URL = "http://%host%/ffgraphs.xml";
const OBSERVATION_URL = "http://%host%/ffgraphs/%graphname%/ffmeasurements.xml";
const PREF_PROFILER = "flock.profiler.enabled";
const PREF_REPORTING = "flock.profiler.reporting.enabled";
const EVENT_FLOCKDATAREADY = "flock-data-ready";
const EVENT_XPCOMSHUTDOWN = "xpcom-shutdown";
var gGraphNames = [];
var gCompTK;
function getCompTK() {
if (!gCompTK) {
gCompTK = Cc["@flock.com/singleton;1"]
.getService(Ci.flockISingleton)
.getSingleton("chrome://browser/content/flock/services/common/load-compTK.js")
.wrappedJSObject;
}
return gCompTK;
}
// ===============================================
// ========== BEGIN flockProfiler class ==========
// ===============================================
function flockProfiler()
{
// Use a logger to spit out data to the console
this._logger = Cc["@flock.com/logger;1"].createInstance(Ci.flockILogger);
this._logger.init("profiler");
// The System Info service will be used to get some performance data
this._sysinfo = Cc["@flock.com/sysinfo;1"].getService(Ci.flockISystemInfo);
var buildInfo = this._sysinfo.getBuildInfo().split(",");
this._platform = buildInfo[0];
this._firstRun = (buildInfo[1] == "1");
this._startTime = (new Date()).getTime();
//this._startTime = this._sysinfo.getStartTime();
var sysinfoTime = this._sysinfo.getStartTime();
this._logger.debug("start time reported by sysinfo:"+sysinfoTime);
this._logger.info("construction time: "+this._startTime);
// Register to observe application initialization and shutdown events
this._obs = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
this.mInitialized = false;
this._obs.addObserver(this, EVENT_FLOCKDATAREADY, false); // calls _init()
this._obs.addObserver(this, EVENT_XPCOMSHUTDOWN, false);
// This will be used to store open profiling events
this._eventQueue = [];
// These will be overridden in _init()
this._profilingEnabled = false;
this._reportingEnabled = false;
// Use Component Toolkit to implement basic interfaces
this._ctk = {
interfaces: [
"nsISupports",
"nsIClassInfo",
"nsISupportsCString",
"nsIObserver",
"flockIProfiler"
],
shortName: "profiler",
fullName: "Flock Profiler",
CID: CLASS_ID,
contractID: CONTRACT_ID
};
}
// BEGIN nsIObserver
flockProfiler.prototype.observe =
function flockProfiler_observe(aSubject, aTopic, aData)
{
switch (aTopic) {
case EVENT_FLOCKDATAREADY:
{
this._obs.removeObserver(this, EVENT_FLOCKDATAREADY);
this._init();
}; break;
case EVENT_XPCOMSHUTDOWN:
{
this._obs.removeObserver(this, EVENT_XPCOMSHUTDOWN);
// Don't accept any more profiling calls or reporting after shutdown
this._profilingEnabled = false;
this._reportingEnabled = false;
// Flush the event queue
this._eventQueue = [];
}; break;
}
}
// END nsIObserver
// BEGIN flockIProfiler
flockProfiler.prototype.profile =
function flockProfiler_profile(aEventName, aMessage)
{
this._init();
if (!this._profilingEnabled) return;
var inst = this;
var pEvent = {
seq: inst._getProfileSeq(),
name: aEventName,
clock: inst._getTimeSinceStart(),
msg: aMessage,
ready: true
};
pEvent.cpu = this._sysinfo.getCPU();
pEvent.mem = this._sysinfo.getMem();
this._eventQueue.push(pEvent);
this._logEvent(pEvent);
}
flockProfiler.prototype.profileEventStart =
function flockProfiler_profileEventStart(aEventName)
{
this._init();
if (!this._profilingEnabled) return 0;
var inst = this;
var pEvent = {
seq: inst._getProfileSeq(),
name: aEventName,
clock: inst._getTimeSinceStart()
};
//pEvent.cpu = this._sysinfo.getCPU();
//pEvent.mem = this._sysinfo.getMem();
this._eventQueue.push(pEvent);
//this._logEvent(pEvent);
return pEvent.seq;
}
flockProfiler.prototype.profileEventEnd =
function flockProfiler_profileEventEnd(aEventID, aMessage)
{
if (!this._profilingEnabled) return;
// Find the event start
var pEvent = null;
for (var i = this._eventQueue.length - 1; i >= 0; i--) {
if (this._eventQueue[i].seq == aEventID) {
pEvent = this._eventQueue[i];
break;
}
}
if (!pEvent) return;
pEvent.duration = this._getTimeSinceStart() - pEvent.clock;
pEvent.cpu = this._sysinfo.getCPU();
pEvent.mem = this._sysinfo.getMem();
pEvent.msg = aMessage;
pEvent.ready = true;
this._logEvent(pEvent);
}
// END flockIProfiler
flockProfiler.prototype._init =
function flockProfiler__init()
{
if (this.mInitialized) return;
// Check prefs to see if we should be enabled
var prefSvc = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefBranch);
this._profilingEnabled = ( prefSvc.getPrefType(PREF_PROFILER) &&
prefSvc.getBoolPref(PREF_PROFILER) );
this._reportingEnabled = ( prefSvc.getPrefType(PREF_REPORTING) &&
prefSvc.getBoolPref(PREF_REPORTING) );
// Kick off a timer for processing the event queue
if (this._profilingEnabled && this._reportingEnabled) {
var inst = this;
var timerCB = { notify: function (aTimer) { inst._processEventQueue(); } };
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(timerCB, 10 * 1000, Ci.nsITimer.TYPE_ONE_SHOT);
}
this.mInitialized = true;
}
flockProfiler.prototype._getProfileSeq =
function flockProfiler__getProfileSeq()
{
return this._eventQueue.length + 1;
}
flockProfiler.prototype._logEvent =
function flockProfiler__logEvent(aEvent)
{
var msg = "";
var props = ["seq","name","clock","duration","cpu","mem","msg"];
for (var p in props) {
if (aEvent[props[p]] == undefined) continue;
if (msg.length > 0) msg += " ";
msg += props[p]+":"+aEvent[props[p]];
}
this._logger.info(msg);
}
flockProfiler.prototype._getTimeSinceStart =
function flockProfiler__getTimeSinceStart()
{
var timeNow = (new Date()).getTime();
var timeElapsed = timeNow - this._startTime;
//dump("CDC profiling: timeNow: "+timeNow+" timeElapsed:"+timeElapsed+"\n");
return timeElapsed;
}
flockProfiler.prototype._ensureGraphExists =
function flockProfiler__ensureGraphExists(aGraphName, aUnits, aListener)
{
if (!this._reportingEnabled) return;
if (gGraphNames[aGraphName] != undefined) {
aListener.onSuccess();
} else {
var inst = this;
var hr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
hr.onreadystatechange = function (aEvent) {
if (hr.readyState == 4) {
gGraphNames[aGraphName] = true;
//inst._logger.info("created graph: "+aGraphName);
//inst._logger.info("graph creation status: "+hr.status+" "+hr.statusText);
//inst._logger.info("response text:"+hr.responseText);
aListener.onSuccess();
}
};
var graphURL = CREATEGRAPH_URL.replace("%host%", GRAPH_HOST)
hr.open("POST", graphURL);
var postBody = "ffgraph[name]="+aGraphName
+ "&ffgraph[units]="+aUnits
+ "&ffgraph[password]=flock";
//inst._logger.info("POST to URL: "+graphURL);
//inst._logger.info("POST body: "+postBody);
hr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
hr.send(postBody);
}
}
flockProfiler.prototype._submitObservations =
function flockProfiler__submitObservations(aProfilingEvent)
{
if (!this._reportingEnabled) return;
var obsTypes = ["clock","duration","cpu","mem"];
var obsUnits = ["ms","ms","%","Mb"];
for (var i in obsTypes) {
var obsType = obsTypes[i];
if (aProfilingEvent[obsType] != undefined) {
switch (obsType) {
case "cpu": case "mem":
// Don't bother recording null observations
if (aProfilingEvent[obsType] == 0) { continue; }
}
var graphName = aProfilingEvent.name+"%20"+obsType+"%20"+this._platform;
if (this._firstRun) graphName += "%20FR";
var inst = this;
var graphCreationListener = {
graphName: graphName,
obsType: obsType,
onSuccess: function () {
if (!inst._reportingEnabled) return;
var hr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
hr.onreadystatechange = function (aHTTPEvent) {
if (hr.readyState == 4) {
aProfilingEvent.sent = true;
}
};
var obsURL = OBSERVATION_URL.replace("%host%", GRAPH_HOST)
.replace("%graphname%", this.graphName);
hr.open("POST", obsURL);
var postBody = "ffmeasurement[data]="+aProfilingEvent[this.obsType]
+ "&ffmeasurement[notes]="+escape(aProfilingEvent.msg);
//inst._logger.info("POST to URL: "+obsURL);
//inst._logger.info("POST body: "+postBody);
hr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
hr.setRequestHeader("Authorization", "Basic OmZsb2Nr"); // Base64(":flock")
hr.send(postBody);
}
};
this._ensureGraphExists(graphName, obsUnits[i], graphCreationListener);
}
}
}
flockProfiler.prototype._processEventQueue =
function flockProfiler__processEventQueue()
{
if (!this._reportingEnabled) return;
//this._logger.info("_processEventQueue()");
while (this._eventQueue.length && this._eventQueue[0].sent) {
this._eventQueue.shift();
}
var profilingEvent = null;
var pos = 0;
while (!profilingEvent && (pos < this._eventQueue.length)) {
if (this._eventQueue[pos].ready) {
profilingEvent = this._eventQueue[pos];
break;
}
pos++;
}
if (profilingEvent) {
this._submitObservations(profilingEvent);
}
var inst = this;
var timerCB = { notify: function (aTimer) { inst._processEventQueue(); } };
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(timerCB, 5 * 1000, Ci.nsITimer.TYPE_ONE_SHOT);
}
// ========== END flockProfiler class ==========
// ================================================
// ========== BEGIN XPCOM Module support ==========
// ================================================
function createModule(aParams) {
return {
registerSelf: function (aCompMgr, aFileSpec, aLocation, aType) {
aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
aCompMgr.registerFactoryLocation( aParams.CID, aParams.componentName,
aParams.contractID, aFileSpec,
aLocation, aType );
var catMgr = Cc["@mozilla.org/categorymanager;1"]
.getService(Ci.nsICategoryManager);
catMgr.addCategoryEntry( "flock-startup", aParams.componentName,
"service,"+aParams.contractID, true, true );
if (!aParams.categories) { aParams.categories = []; }
for (var i = 0; i < aParams.categories.length; i++) {
var cat = aParams.categories[i];
catMgr.addCategoryEntry( cat.category, cat.entry,
cat.value, true, true );
}
},
getClassObject: function (aCompMgr, aCID, aIID) {
if (!aCID.equals(aParams.CID)) { throw Cr.NS_ERROR_NO_INTERFACE; }
if (!aIID.equals(Ci.nsIFactory)) { throw Cr.NS_ERROR_NOT_IMPLEMENTED; }
return { // Factory
createInstance: function (aOuter, aIID) {
if (aOuter != null) { throw Cr.NS_ERROR_NO_AGGREGATION; }
var comp = new aParams.componentClass();
if (aParams.implementationFunc) { aParams.implementationFunc(comp); }
return comp.QueryInterface(aIID);
}
};
},
canUnload: function (aCompMgr) { return true; }
};
}
// NS Module entrypoint
function NSGetModule(aCompMgr, aFileSpec) {
return createModule({
componentClass: flockProfiler,
CID: CLASS_ID,
contractID: CONTRACT_ID,
componentName: CATEGORY_COMPONENT_NAME,
implementationFunc: function (aComp) { getCompTK().addAllInterfaces(aComp); }
});
}
// ========== END XPCOM Module support ==========